import com.google.common.collect.Ordering;
import com.google.common.primitives.Booleans;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Created with IntelliJ IDEA.
 * User: Gauss
 * Date: 26.03.14
 * Time: 10:13
 * To change this template use File | Settings | File Templates.
 */
public class MyConcurrentCalculator implements FileSizeCalculator {

    private volatile AtomicLong size;

    @Override
    public long calculateSize(String fileName) throws IOException {
        size = new AtomicLong(0);
        File file = new File(fileName);
        return calculateSize(file);
    }

    private long calculateSize(File root) {
        if (root.isFile()) {
            return root.length();
        }
        new CalculatorRunnable(root).run();
        return size.longValue();
    }

    private class CalculatorRunnable implements Runnable  {

        private File file;

        private CalculatorRunnable(File file) {
            this.file = file;
        }

        @Override
        public void run() {
            File[] filesInDirectory = file.listFiles();
            if (filesInDirectory == null || filesInDirectory.length == 0) {
                return;
            }
            List<File> directories = new ArrayList<File>();
            //ThreadGroup group = new ThreadGroup(String.valueOf(this.hashCode()));
            for (File temp: filesInDirectory) {
                if (temp.isFile()) {
                    size.addAndGet(temp.length());
                } else {
                    directories.add(temp);
                }
            }
            if (directories.size()==0) {
                return;
            }
            Thread[] group = new Thread[directories.size()-1];
            for (int i=0;i<directories.size()-1; i++) {
                Thread thread = new Thread(new CalculatorRunnable(directories.get(i)));
                group[i] = thread;
                thread.start();
            }
            this.file = directories.get(directories.size()-1);
            run();
            for (Thread thread: group) {
                try {
                    thread.join();
                } catch (InterruptedException ignored) {}
            }
        }

    }

    @Override
    public String getName() {
        return "MyConcurrentCalculator";
    }

}
